package com.kexio.user.service;

import java.util.List;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kexio.user.entity.Menu;
import com.kexio.user.entity.Permission;
import com.kexio.user.entity.Role;
import com.kexio.user.entity.User;

/**
 * 角色服务接口
 * 
 * 提供角色管理的核心业务逻辑，包括：
 * - 角色CRUD操作
 * - 角色权限关联管理
 * - 角色用户关联管理
 * - 数据权限配置
 * - 多租户数据隔离
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
public interface RoleService {
    
    // ==================== 基础CRUD操作 ====================
    
    /**
     * 创建角色
     * 
     * @param role 角色信息
     * @return 创建的角色信息
     */
    Role createRole(Role role);
    
    /**
     * 根据ID更新角色信息
     * 
     * @param roleId 角色ID
     * @param role 更新的角色信息
     * @return 更新后的角色信息
     */
    Role updateRole(String roleId, Role role);
    
    /**
     * 根据ID删除角色（逻辑删除）
     * 
     * @param roleId 角色ID
     * @return 是否删除成功
     */
    boolean deleteRole(String roleId);
    
    /**
     * 根据ID查询角色信息
     * 
     * @param roleId 角色ID
     * @return 角色信息
     */
    Role getRoleById(String roleId);
    
    /**
     * 根据角色编码查询角色信息
     * 
     * @param roleCode 角色编码
     * @return 角色信息
     */
    Role getRoleByCode(String roleCode);
    
    // ==================== 角色列表查询 ====================
    
    /**
     * 分页查询角色列表
     * 
     * @param current 当前页码
     * @param size 每页大小
     * @return 分页角色列表
     */
    Page<Role> getRolePage(Long current, Long size);
    
    /**
     * 带条件分页查询角色列表
     * 
     * @param current 当前页码
     * @param size 每页大小
     * @param roleCode 角色编码（可选）
     * @param roleName 角色名称（可选）
     * @param status 状态（可选）
     * @return 分页角色列表
     */
    Page<Role> getRolePage(Long current, Long size, String roleCode, String roleName, Integer status);
    
    /**
     * 查询所有角色
     * 
     * @return 角色列表
     */
    List<Role> getAllRoles();
    
    /**
     * 查询启用状态的角色列表
     * 
     * @return 启用角色列表
     */
    List<Role> getActiveRoles();
    
    /**
     * 根据状态查询角色列表
     * 
     * @param status 角色状态
     * @return 角色列表
     */
    List<Role> getRolesByStatus(String status);
    
    // ==================== 角色权限管理 ====================
    
    /**
     * 查询角色拥有的权限列表
     * 
     * @param roleId 角色ID
     * @return 权限列表
     */
    List<Permission> getRolePermissions(String roleId);
    
    /**
     * 查询角色拥有的权限编码列表
     * 
     * @param roleId 角色ID
     * @return 权限编码列表
     */
    List<String> getRolePermissionCodes(String roleId);
    
    /**
     * 为角色分配权限
     * 
     * @param roleId 角色ID
     * @param permissionIds 权限ID列表
     * @param operatorId 操作者ID
     * @return 是否分配成功
     */
    boolean assignPermissions(String roleId, List<String> permissionIds, String operatorId);
    
    /**
     * 移除角色的权限
     * 
     * @param roleId 角色ID
     * @param permissionIds 权限ID列表
     * @return 是否移除成功
     */
    boolean removePermissions(String roleId, List<String> permissionIds);
    
    /**
     * 同步角色权限（先清除再分配）
     * 
     * @param roleId 角色ID
     * @param permissionIds 新的权限ID列表
     * @param operatorId 操作者ID
     * @return 是否同步成功
     */
    boolean syncPermissions(String roleId, List<String> permissionIds, Long operatorId);
    
    // ==================== 角色用户管理 ====================
    
    /**
     * 查询角色下的用户列表
     * 
     * @param roleId 角色ID
     * @return 用户列表
     */
    List<User> getRoleUsers(String roleId);
    
    /**
     * 查询用户拥有的角色列表
     * 
     * @param userId 用户ID
     * @return 角色列表
     */
    List<Role> getUserRoles(String userId);
    
    /**
     * 为角色分配用户
     * 
     * @param roleId 角色ID
     * @param userIds 用户ID列表
     * @param operatorId 操作者ID
     * @return 是否分配成功
     */
    boolean assignUsers(String roleId, List<String> userIds, Long operatorId);
    
    /**
     * 移除角色的用户
     * 
     * @param roleId 角色ID
     * @param userIds 用户ID列表
     * @return 是否移除成功
     */
    boolean removeUsers(String roleId, List<String> userIds);
    
    /**
     * 同步角色用户（先清除再分配）
     * 
     * @param roleId 角色ID
     * @param userIds 新的用户ID列表
     * @param operatorId 操作者ID
     * @return 是否同步成功
     */
    boolean syncUsers(String roleId, List<String> userIds, Long operatorId);
    
    // ==================== 角色菜单管理 ====================
    
    /**
     * 查询角色关联的菜单列表
     * 
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 菜单列表
     */
    List<Menu> getRoleMenus(String roleId, String tenantId);
    
    /**
     * 查询角色菜单树结构
     * 
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 菜单树列表
     */
    List<Menu> getRoleMenuTree(String roleId, String tenantId);
    
    /**
     * 为角色分配菜单
     * 
     * @param roleId 角色ID
     * @param menuIds 菜单ID列表
     * @param operatorId 操作者ID
     * @return 是否分配成功
     */
    boolean assignMenus(String roleId, List<String> menuIds, String operatorId);
    
    // ==================== 数据权限管理 ====================
    
    /**
     * 查询角色的数据权限范围
     * 
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 数据权限信息（JWT架构下已简化）
     */
    Object getRoleDataScope(String roleId, String tenantId);
    
    /**
     * 查询用户的数据权限范围（通过角色）
     * 
     * @param userId 用户ID
     * @param tenantId 租户ID
     * @return 数据权限信息列表（JWT架构下已简化）
     */
    List<Object> getUserDataScope(String userId, String tenantId);
    
    /**
     * 更新角色的数据权限配置
     * 
     * @param roleId 角色ID
     * @param dataScope 数据权限类型
     * @param deptIds 部门ID列表（自定义权限时使用）
     * @param tenantId 租户ID
     * @param operatorId 操作者ID
     * @return 是否更新成功
     */
    boolean updateDataScope(String roleId, String dataScope, List<String> deptIds, String tenantId, Long operatorId);
    
    // ==================== 角色层级管理 ====================
    
    /**
     * 查询角色的直接子角色
     * 
     * @param parentRoleId 父角色ID
     * @param tenantId 租户ID
     * @return 子角色列表
     */
    List<Role> getChildRoles(Long parentRoleId, String tenantId);
    
    /**
     * 查询角色的所有祖先角色
     * 
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 祖先角色列表
     */
    List<Role> getAncestorRoles(String roleId, String tenantId);
    
    /**
     * 查询角色的所有后代角色
     * 
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 后代角色列表
     */
    List<Role> getDescendantRoles(String roleId, String tenantId);
    
    // ==================== 权限检查 ====================
    
    /**
     * 检查角色是否拥有指定权限
     * 
     * @param roleId 角色ID
     * @param permissionCode 权限编码
     * @param tenantId 租户ID
     * @return 是否拥有权限
     */
    boolean hasPermission(String roleId, String permissionCode, String tenantId);
    
    /**
     * 检查角色是否拥有任一权限
     * 
     * @param roleId 角色ID
     * @param permissionCodes 权限编码列表
     * @param tenantId 租户ID
     * @return 是否拥有任一权限
     */
    boolean hasAnyPermission(String roleId, List<String> permissionCodes, String tenantId);
    
    /**
     * 检查用户是否拥有指定角色
     * 
     * @param userId 用户ID
     * @param roleCode 角色编码
     * @param tenantId 租户ID
     * @return 是否拥有角色
     */
    boolean hasRole(String userId, String roleCode, String tenantId);
    
    // ==================== 统计查询 ====================
    
    /**
     * 统计租户角色总数
     * 
     * @param tenantId 租户ID
     * @return 角色总数
     */
    Long countRolesByTenant(String tenantId);
    
    /**
     * 统计启用的角色数量
     * 
     * @param tenantId 租户ID
     * @return 启用角色数
     */
    Long countActiveRoles(String tenantId);
    
    /**
     * 统计角色分配给的用户数量
     * 
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 用户数量
     */
    Long countRoleUsers(String roleId, String tenantId);
    
    // ==================== 数据验证 ====================
    
    /**
     * 检查角色编码是否存在
     * 
     * @param roleCode 角色编码
     * @param excludeRoleId 排除的角色ID（用于更新时检查）
     * @return 是否存在
     */
    boolean existsByCode(String roleCode, String excludeRoleId);
    
    /**
     * 检查角色名称是否存在
     * 
     * @param roleName 角色名称
     * @param excludeRoleId 排除的角色ID（用于更新时检查）
     * @return 是否存在
     */
    boolean existsByName(String roleName, String excludeRoleId);
    
    /**
     * 检查角色是否被使用（是否有用户分配）
     * 
     * @param roleId 角色ID
     * @param tenantId 租户ID
     * @return 是否被使用
     */
    boolean isRoleInUse(String roleId, String tenantId);
    
    /**
     * 获取角色分布统计
     * 
     * @return 角色名称 -> 用户数的映射
     */
    java.util.Map<String, Long> getRoleDistributionStats();
}
